#! /bin/env python
#-*- encoding:utf-8 -*-

'''
//******************************************************************************
// Author:  qujianning@100tal.com
// Date:    2014/08/27
// Ver:     1.0.0
// Desc:    squid cache refresh python script
// GIT:     https://git.oschina.net/redfox.qu/xes_curl_test.git
//******************************************************************************
'''

import os
import re
import json
import time
import sys
import hashlib
import httplib
import urllib
import urllib2
import platform
import datetime
import syslog

reload(sys)
sys.setdefaultencoding("utf-8")

plat        = 'squid'
sys         = 'speiyou'
skey        = 'com.xes.itempool'
#srv_name   = socket.gethostname()
srv_name    = '10016_bj_hdhz1_ics3' # just for test
res_uri     = 'http://icsinterface.speiyou.com/icsinterface/rest/curriculum/queryCacheAndQuesByHostName'

cw_plat     = 'flex'
cw_sys      = 'ics3'
cw_uri      = 'http://itiku.speiyou.com/itempool/rest/question/queryQuestionByIds.json'

stu_uri     = 'http://115.182.69.75:8080/icsinterface/rest/curriculum/cacheStuLogin?hostName'
tea_uri     = 'http://115.182.69.75:8080/icsinterface/rest/curriculum/cacheTeaLogin?hostName'
cls_uri     = 'http://115.182.69.75:8080/icsinterface/rest/curriculum/cacheClassType?hostName'

squid_ip    = '127.0.0.1'
squid_port  = '80'
timeout     = 10

'''
#****************************************************************
#             example resouce-list json result                  #
#****************************************************************
'result': {
    'msg': 'ok',
    'rlt': 'True',
    'coursewares': [
        'http://10.1.250.71:8080/ICSmananger/upload/coursewaresource/11401339779640/lecture.ics',
        'http://10.1.250.71:8080/ICSmananger/upload/videos/5938d678-facb-45b9-9d40-700368f472e3.mp4',
        'http://10.1.250.71:8080/ICSmananger/upload/videos/5938d678-facb-45b9-9d40-700368f472e3.jpg',
        'http://10.1.250.71:8080/ICSmananger/upload/videos/85de8341-4d70-4230-8923-0e36fded2414.mp4',
        'http://10.1.250.71:8080/ICSmananger/upload/videos/85de8341-4d70-4230-8923-0e36fded2414.jpg',
        'http://10.1.250.71:8080/ICSmananger/upload/videos/9d0a0ab3-2310-436d-9061-56656f63e0b6.mp4',
        'http://10.1.250.71:8080/ICSmananger/upload/videos/9d0a0ab3-2310-436d-9061-56656f63e0b6.jpg'
    ],
    'questions': [
        '07fea5cdead4426597e75f4b2d086bbb',
        '3a7be5aa75eb415e8c1587085a4c6e5d',
        '4d04a01e598749d6bec8eb3846db79c1',
        '5e79aae3fe704e16b0193ca793123599'
    ]
}
'''

def mk_md5_str(telid='', plat='', sys='', skey=''):
    join_str = "%s%s%s%s" % (telid, plat, sys, skey)
    md5_str = hashlib.md5(join_str.encode("utf-8")).hexdigest()
    return md5_str

def get_res_list():
    print "%-10s: %s" % ("hostname", srv_name)
    md5str = mk_md5_str(srv_name, plat, sys, skey)
    print "%-10s: %s" % ("md5str", md5str)

    res_query = 'hostName=%s' % (srv_name)
    res_url = "%s?%s" % (res_uri, res_query)
    print "%-10s: %s" % ("res_url", res_url)

    headers = {
            'User-Agent'    : 'Cache Squid python',
            'Accept'        : '*/*',
            'Connect-type'  : 'text/plain',
            'plat'          : plat,
            'sys'           : sys,
            'md5'           : md5str,
            'key'           : skey
            }
    try:
        res_req = urllib2.Request(res_url, headers=headers)
        res_rsp = urllib2.urlopen(res_req, timeout=timeout).read()
        print "%-10s: %s" % ("res_rsp", res_rsp)
        return res_rsp
    except Exception, n:
        syslog.syslog(syslog.LOG_ERR, "error: connect ics intf error! %s" % str(n))
        #exit(1)
    return

def check_net_link(url):
    host = urllib2.urlparse.urlsplit(url).netloc
    ping_ret = os.popen("ping -c4 %s" % (host)).read()
    loss_pct = re.findall(r"(\d+)% packet loss", ping_ret, re.M)
    if loss_pct and loss_pct[0] == '0':
        return True
    return False

def cache_purge(ip, port, url):
    http_headers = {
            'Host'          : 'CacheRefresher',
            'User-Agent'    : 'SquidClient',
            'Accept'        : '*/*',
            }
    conn = httplib.HTTPConnection(ip, port, timeout=timeout)
    conn.request('PURGE', url, headers = http_headers)
    return

def get_proxy_opener(proxy_ip, proxy_port):
    proxy = {
            'http'          : 'http://%s:%s' % (proxy_ip, proxy_port),
            }
    proxy_handler = urllib2.ProxyHandler(proxy)
    opener = urllib2.build_opener(proxy_handler)
    return opener

def refresh_questions_cache(questions):
    opener = get_proxy_opener(squid_ip, squid_port)
    for url in questions:
        try:
            if check_net_link(url) == False:
                syslog.syslog(syslog.LOG_WARNING, "warning: net check is unreachable")
                continue
            cache_purge(squid_ip, squid_port, url)
            opener.open(url, timeout=timeout).read()
            syslog.syslog(syslog.LOG_INFO, "refresh question %s" % (url))
            print "%-10s: %s" % ("RET", "refresh question %s" % (url))
        except Exception, n:
            syslog.syslog(syslog.LOG_ERR, "error: refresh question error! %s" % str(n))
            #exit(1)
    return

def refresh_coursewares_cache(coursewares):
    opener = get_proxy_opener(squid_ip, squid_port)
    for ids in coursewares:
        md5str = mk_md5_str(ids, cw_plat, cw_sys, skey)
        url = '%s?%s' % (cw_uri, ids)
        try:
            if check_net_link(url) == False:
                syslog.syslog(syslog.LOG_WARNING, "warning: net check is unreachable")
                continue
            cache_purge(squid_ip, squid_port, url)
            headers = {
                'User-Agent'    : 'Cache Squid python',
                'Accept'        : '*/*',
                'Connect-type'  : 'text/plain',
                'plat'          : cw_plat,
                'sys'           : cs_sys,
                'md5'           : md5str,
                }
            cw_req = urllib2.Request(url, headers=headers)
            cw_rsp = opener.open(cw_req, timeout=timeout).read()
            syslog.syslog(syslog.LOG_INFO, "refresh coursewares %s" % (url))
            print "%-10s: %s" % ("RET", "refresh coursewares %s" % (url))
        except Exception, n:
            syslog.syslog(syslog.LOG_ERR, "error: refresh question error! %s" % str(n))
            #exit(1)
    return

def get_student_list():
    #print "%-10s: %s" % ("hostname", srv_name)
    stu_url = "%s=%s" % (stu_uri, srv_name)
    print "%-10s: %s" % ("stu_url", stu_url)
    headers = {
            'User-Agent'    : 'Cache Squid python',
            'Accept'        : '*/*',
            'Connect-type'  : 'text/plain',
            }
    try:
        stu_req = urllib2.Request(stu_url, headers=headers)
        stu_rsp = urllib2.urlopen(stu_req, timeout=timeout).read()
        print "%-10s: %s" % ("stu_rsp", stu_rsp)
        return stu_rsp
    except Exception, n:
        syslog.syslog(syslog.LOG_ERR, "error: connect ics intf error! %s" % str(n))
        #exit(1)
    return None

def refresh_login(l):
    '''
    for k, v in l.items():
        print k, v
    print ""
    '''
    opener = get_proxy_opener(squid_ip, squid_port)
    try:
        '''
        if check_net_link(stu['url']) == False:
            syslog.syslog(syslog.LOG_WARNING, "warning: net check is unreachable")
            return
        '''
        #print unicode(l['url'])
        #url = unicode(l['url']).decode('utf-8')
        #print url
        cache_purge(squid_ip, squid_port, l['url'])
        headers = {
            'User-Agent'    : 'Cache Squid python',
            'Accept'        : '*/*',
            'Connect-type'  : 'text/plain',
            'plat'          : l['plat'],
            'sys'           : l['sys'],
            'md5'           : l['md5'],
            }
        l_req = urllib2.Request(l['url'], headers=headers)
        l_rsp = opener.open(l_req, timeout=timeout).read()
        syslog.syslog(syslog.LOG_INFO, "refresh login %s" % (l['url']))
        print "%-10s: %s" % ("RET", "refresh coursewares %s" % (l['url']))
        print ""
    except Exception, n:
        syslog.syslog(syslog.LOG_ERR, "error: refresh login %s error! %s" % (l['url'], str(n)))
        print "%-10s: %s" % ("RET", "error: refresh login %s error! %s" % (l['url'], str(n)))
        #exit(1)
    return

def get_teacher_list():
    #print "%-10s: %s" % ("hostname", srv_name)
    tea_url = "%s=%s" % (tea_uri, srv_name)
    print "%-10s: %s" % ("tea_url", tea_url)
    headers = {
            'User-Agent'    : 'Cache Squid python',
            'Accept'        : '*/*',
            'Connect-type'  : 'text/plain',
            }
    try:
        tea_req = urllib2.Request(tea_url, headers=headers)
        tea_rsp = urllib2.urlopen(tea_req, timeout=timeout).read()
        print "%-10s: %s" % ("tea_rsp", tea_rsp)
        return tea_rsp
    except Exception, n:
        syslog.syslog(syslog.LOG_ERR, "error: connect ics intf error! %s" % str(n))
        #exit(1)
    return None

def get_class_list():
    #print "%-10s: %s" % ("hostname", srv_name)
    cls_url = "%s=%s" % (cls_uri, srv_name)
    print "%-10s: %s" % ("cls_url", cls_url)
    headers = {
            'User-Agent'    : 'Cache Squid python',
            'Accept'        : '*/*',
            'Connect-type'  : 'text/plain',
            }
    try:
        cls_req = urllib2.Request(cls_url, headers=headers)
        cls_rsp = urllib2.urlopen(cls_req, timeout=timeout).read()
        print "%-10s: %s" % ("cls_rsp", cls_rsp)
        return cls_rsp
    except Exception, n:
        syslog.syslog(syslog.LOG_ERR, "error: connect ics intf error! %s" % str(n))
        #exit(1)
    return None

if __name__ == '__main__':
    #open syslog
    syslog.openlog("ics30_cache_script_py")

    # refresh question/coursewares
    ics_refresh = 0
    ics_res = json.loads(get_res_list())
    if ics_res.has_key('result') and ics_res['result'].has_key('questions'):
        refresh_questions_cache(ics_res['result']['questions'])
        ics_refresh = ics_refresh + 1
    if ics_res.has_key('result') and ics_res['result'].has_key('coursewares'):
        refresh_coursewares_cache(ics_res['result']['coursewares'])
        ics_refresh = ics_refresh + 1
    if ics_refresh == 0:
        syslog.syslog(syslog.LOG_INFO, "nothing cache would be refreshed.")
        print "%-10s: %s" % ("RET", "nothing cache would be refreshed.")
        #exit(1)

    # student login cache refresh
    stu_lst = json.loads(get_student_list())
    if stu_lst.has_key('result') and stu_lst['result'].has_key('stuList'):
        for stu_i in stu_lst['result']['stuList']:
            refresh_login(stu_i)
    # teacher login cache refresh
    tea_lst = json.loads(get_teacher_list())
    if tea_lst.has_key('result') and tea_lst['result'].has_key('teaList'):
        for tea_i in tea_lst['result']['teaList']:
            refresh_login(tea_i)
    # class information cache refresh
    cls_lst = json.loads(get_class_list())
    if cls_lst.has_key('result') and cls_lst['result'].has_key('ctList'):
        for cls_i in cls_lst['result']['ctList']:
            refresh_login(cls_i)

    syslog.closelog()
    exit(0)

